package lucky.xiong.certifacte.加解密;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;

/**
 * Created by lihong10 on 2017/8/16.
 */
public class AESCBC {

    //算法/模式/填充
    private static final String CipherMode = "AES/CBC/PKCS5Padding";

    /**
     * 创建密钥
     *
     * @param key
     * @return
     */
    private static SecretKeySpec createKey(String key) {
       
        byte[] data =  key.substring(0, 16).getBytes();
        return new SecretKeySpec(data, "AES");
    }

    /**
     * 创建初始化向量
     *
     * @param password
     * @return
     */
    private static IvParameterSpec createIV(String password) {
       
        byte[] data = password.substring(16).getBytes();;
        
        return new IvParameterSpec(data);
    }

    /**
     * AES-128/CBC算法加密字节数据
     *
     * @param content
     * @param password 密钥
     * @param iv       初始化向量
     * @return byte[]
     */
    public static byte[] aes128CBCEncrypt(byte[] content, String password) {
        try {
            Cipher cipher = Cipher.getInstance(CipherMode);
            cipher.init(Cipher.ENCRYPT_MODE, createKey(password), createIV(password));
            byte[] result = cipher.doFinal(content);
            return result;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * AES-128/CBC算法解密字节数组
     *
     * @param content
     * @param password 密钥
     * @param iv       初始化向量
     * @return byte[]
     */
    public static byte[] aes128CBCDecrypt(byte[] content, String password) {
        try {
            Cipher cipher = Cipher.getInstance(CipherMode);
            cipher.init(Cipher.DECRYPT_MODE, createKey(password), createIV(password));
            byte[] result = cipher.doFinal(content);
            return result;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    /**
     * 将buf 转成16进制
     * @param buf
     * @return
     */
    public static String parseByte2HexStr(byte[] buf)
     {
       StringBuffer sb = new StringBuffer();
        for (int i = 0; i < buf.length; i++) {
         String hex = Integer.toHexString(buf[i] & 0xFF);
          if (hex.length() == 1) {
         hex = '0' + hex;
     }
          sb.append(hex.toUpperCase());
        }
        return sb.toString();
     }
    /**
     * 将字符串转byte
     * @param hexStr
     * @return
     */
    public static byte[] parseHexStr2Byte(String hexStr)
      {
        if (hexStr.length() < 1)
        return null;
        byte[] result = new byte[hexStr.length() / 2];
        for (int i = 0; i < hexStr.length() / 2; i++) {
        int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
           int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 
            16);
          result[i] = ((byte)(high * 16 + low));
      }
        return result;
   }


    public static void main(String... args) throws UnsupportedEncodingException {

    	 /*
         * 此处使用AES-128-CBC加密模式
         */
        String authKey = "2800c980501542339f284770e1488f34";
        // 需要加密的字串
        String cSrc = "SSMC|13:2124444";
        System.out.println("原值：" + cSrc);
        byte[] b= aes128CBCEncrypt(cSrc.getBytes("UTF-8"), authKey);
        String secKey = parseByte2HexStr(b);
        System.out.println("加密：" + secKey);
        
        byte[] bs= aes128CBCDecrypt(parseHexStr2Byte(secKey), authKey);
        System.out.println("解密：" + new String(bs));
    }


}
